# -*- coding: utf-8 -*-
import FPLib
import os
import importlib
import traceback
import string
# import tornado.gen
# import asyncio


class Page(object):
    """Page."""

    hashList = {}

    def __init__(self, server):
        super(Page, self).__init__()
        self.server = server
        self.is_cached = False
        self.cache = []
        # asyncio.set_event_loop(asyncio.new_event_loop())

    def cached(self, enable=True):
        self.is_cached = enable

    def getcache(self):
        cacheData = b''.join(self.cache)
        self.cache.clear()
        return cacheData

    def addcache(self, data):
        if data:
            if isinstance(data, str):
                data = data.encode()
            self.cache.append(data)

    def goto(self, url):
        # self.header("Location", url)
        self.server.redirect(url)

    def js(self, data):
        if isinstance(data, str):
            data = [data.encode()]
        html = self.server.render_embed_js(data)
        self.out(html)

    def css(self, data):
        if not isinstance(data, list):
            data = [data]
        html = self.server.render_embed_css(data)
        self.out(html)

    def outJS(self, name, *args, **kwargs):
        return self.js(self.getLocalFile(name, ".js", *args, **kwargs))

    def outCSS(self, name, *args, **kwargs):
        return self.css(self.getLocalFile(name, ".css", *args, **kwargs))

    def jsfile(self, data):
        if not isinstance(data, list):
            data = [data]
        html = self.server.render_linked_js(data)
        self.out(html)

    def cssfile(self, data):
        if not isinstance(data, list):
            data = [data]
        html = self.server.render_linked_css(data)
        self.out(html)

    def UI(self, name, *args, **kwargs):
        template_path = self.server.get_template_path()
        ui_path = os.path.normpath(os.path.join(template_path, name))

        listHash = ui_path
        module = None

        try:
            if not FPLib.conf.isdebug:
                if listHash in self.hashList:
                    # print("find")
                    module = self.hashList.get(listHash)

            if not module:
                module = FPLib.ModuleLoader.load(listHash, listHash)
                self.hashList[listHash] = module

            if module:
                if hasattr(module, "UI"):
                    func = getattr(module, "UI")
                    self.cached(True)
                    tmpData = func(self, self.server, self.server.request, *args, **kwargs)
                    self.cached(False)
                    if tmpData:
                        self.addcache(tmpData)
                    return self.getcache()
        except Exception as e:
            print(e)
            pass
        return ""

    def out(self, data):
        try:
            if self.is_cached:
                self.addcache(data)
            else:
                self.server.write(data)
            # self.server.flush()
        except Exception as e:
            FPLib.findError(e)
            print("Page Out Error:", e)

    def outHTML(self, name, *args, **kwargs):
        return self.out(self.HTML(name, *args, **kwargs))

    def getLocalFile(self, name, extension=".", *args, **kwargs):
        htmls = ""
        try:
            f, ext = os.path.splitext(name)
            if ext == ".py":
                name = f + extension
            file = open(name, 'r')
            htmls = file.read()
            # if kwargs:
            t = string.Template(htmls)
            htmls = t.safe_substitute(*args, **kwargs)
        except Exception as e:
            raise

        return htmls

    def HTML(self, name, *args, **kwargs):
        return self.getLocalFile(name, ".html", *args, **kwargs)

    def outT(self, name, *args, **kwargs):
        return self.out(self.T(name, *args, **kwargs))

    def T(self, name, *args, **kwargs):
        f, ext = os.path.splitext(name)
        if ext == ".py":
            name = f + ".html"
        kwargs.setdefault("Page", self)
        return self.server.render_string(name, *args, **kwargs)

    def nocache(self):
        self.server.set_header("Cache-Control", "no-cache, must-revalidate")
        self.server.set_header("Pragma", "no-cache")

    def header(self, key, value=""):
        self.server.set_header(key, value)

    def call_404(self):
        self.server.write("404 Page Not Found")
